//== SAGITTARIUS ============================================================================

//== BEGINNING OF CODE ===============================================================

#ifndef __SAGUTTARUIS__SPAN__H_
#define __SAGUTTARUIS__SPAN__H_

//== INCLUDES ========================================================================

#include "sagittarius/core/SagittariusCore.h"
#include "sagittarius/mem/sysalloc.h"
#include "sagittarius/mem/sizeclass.h"
#include "sagittarius/parallel/multisema.h"

#define SPAN_HDR_GROWTH 4 //lshift

#ifdef __cplusplus
extern "C" {
#endif

#define SG_SPAN_FREENODE_SIZE   4
#define SG_FREENODE_EXH         0x7FFFFFFF //first bit is absent to distinguish allocated and non-allocated blocks
#define SG_SPAN_OFFSET_MAX      (SG_FREENODE_EXH-1)
typedef uint32                  freenode_t;

typedef struct {
    void* addr;
    freenode_t freenode;
    freenode_t instnode;
    size_t np; //# pages
    size_t bs; //size of block
    size_t no; //number of objects
    size_t ob; //size of object (in bytes)
    size_t sbmp; //size of bitmap (in bytes)
    size_t bb; //bitmap bits
    sg_sclass sc;
    SG_DEF_MULTISEMA(sema);
} sg_span;

//size_t align_tpb(size_t b);

void* get_pgboundary(void* addr);

//initialize span
int init_span(sg_span* s, void* addr, size_t np, uint32 bb);

//small objects
void* smo_allocs_b(sg_span* s);
int smo_frees(sg_span* s, void* obj);
//int smo_push_direct(sg_span* s, void* obj);

void* sg_get_smo_addr(void* start, size_t off, size_t bs);
size_t sg_get_smo_header(void* obj, size_t bs);

void span_dump_sate(int fd, sg_span* s);

#ifdef __cplusplus
}//extern "C"
#endif

#endif
